from random import randint
import re

from django.conf import settings
<<<<<<< HEAD
=======
from django.contrib.auth.hashers import make_password
from django.http import JsonResponse
from django.shortcuts import HttpResponse
>>>>>>> origin/findpassword
from rest_framework.generics import CreateAPIView, RetrieveAPIView, UpdateAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from django_redis import get_redis_connection
from rest_framework_extensions.cache.mixins import CacheResponseMixin
from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.views import ObtainJSONWebToken

from celery_tasks.sms.task import send_sms_code
from celery_tasks.sms.yuntongxun.sms import CCP
from itsdangerous import TimedJSONWebSignatureSerializer as TJS

# Create your views here.
from meiduo.utils.captcha import captcha
from users.models import User
from users.serializers import UserSerializer, UserDetailSerializer, UserUpdateSerializer
from users.utils import merge_cart_cookie_to_redis


class SmsCodeView(APIView):
    def get(self, request, mobile):
        conn = get_redis_connection('sms_session')
        flag = conn.get('mobile_flag_%s' % mobile)
        if flag:
            return Response({'massage': '先森，你的要求很频繁腻～'})

        # 生成验证码
        sms_code = '%06d' % randint(0, 999999)
        print(sms_code)

        pl = conn.pipeline()
        pl.setex('mobile_%s' % mobile, 300, sms_code)
        pl.setex('mobile_flag_%s' % mobile, 60, sms_code)
        pl.execute()

        send_sms_code.delay(mobile, sms_code, 120)

        return Response({'massage': 'ok'})


class MobilesView(APIView):
    def get(self, request, mobile):
        count = User.objects.filter(mobile=mobile)

        return Response({'count': count})


class UsernameView(APIView):
    def get(self, request, username):
        count = User.objects.filter(username=username)

        return Response({'count': count})


class UserView(CreateAPIView):
    serializer_class = UserSerializer


class UserDetailView(RetrieveAPIView):
    serializer_class = UserDetailSerializer
    permission_classes = [IsAuthenticated]  # 权限指定

    def get_object(self):
        return self.request.user


class UserUpdateView(UpdateAPIView):
    serializer_class = UserUpdateSerializer

    def get_object(self):
        return self.request.user

class ModifyPasswordView(APIView):
    """
    修改密码
    old_password: vm.old_pwd,
    password: vm.new_pwd,
    password2: vm.new_cpwd
    """
    def put(self,request,pk):
        data=request.data
        user = User.objects.get(id=pk)
        if not user.check_password(data['old_password']):
            raise Exception({'message':'原密码输入错误'})
        if data['password'] != data['password2']:
            raise Exception({'message':'输入新密码不一致'})
        if data['old_password'] == data['password']:
            raise Exception({'message':'新密码与旧密码不能一致'})
        user.set_password(data['password'])
        user.save()
        return Response({'message':'ok'})



class EmailVerifyView(CacheResponseMixin, APIView):

    def get(self, request):
        token = request.query_params.get('token')
        tjs = TJS(settings.SECRET_KEY, 300)
        try:
            data = tjs.loads(token)
        except:
            return Response({'error': '邮件验证失败'}, status=400)

        username = data['name']
        try:
            user = User.objects.get(username=username)
        except:
            return Response({'error': '没有这个沙雕用户'}, status=400)

        user.email_active = True
        user.save()

        return Response({'massage': True})


class UserLoginView(ObtainJSONWebToken):

    def post(self, request, *args, **kwargs):
        response = super().post(request, *args, **kwargs)

        serializer = self.get_serializer(data=request.data)

        if serializer.is_valid():
            user = serializer.object.get('user') or request.user
            # 合并购物车
            response = merge_cart_cookie_to_redis(request, user, response)

        return response


class ImageCode(APIView):
    def get(self, request, uuid):
        # 判断前端是否传入uuid，如果没传入，返回结果
        print(uuid)
        if not uuid:
            return Response({'error':'缺少参数ｕｕｉｄ'}, status=400)
        # 调用ｃａｐｔｃｈａ工具生成图片验证码
        name, text, image = captcha.captcha.generate_captcha()
        # 把图片验证码的ｔｅｘｔ文本存储在ｒｅｄｉｓ中
        conn = get_redis_connection('image_code')
        # 以ｓｔｒｉｎｇ类型写入ｒｅｄｉｓ中
        conn.setex('image_code_%s' % uuid, 300, text)
        # 使用响应对象来返回图片
        return HttpResponse(image, content_type='image.jpg')


class CheckImage(APIView):
    def get(self, request, username):
        # 获取前端传入的参数
        text = request.query_params.get('text')
        uuid = request.query_params.get('image_code_id')
        # 判断用户名是否存在
        try:
            user = User.objects.get(username=username)
        except:
            user = User.objects.filter(mobile=username)
            if not user:
                return Response({'error': '用户名或手机号不存在'}, status=404)
        # 获取ｒｅｄｉｓ数据库中的图片验证码
        mobile = user.mobile
        conn = get_redis_connection('image_code')
        real_text = conn.get('image_code_%s' % uuid).decode()
        if not real_text.lower() == text.lower():
            return Response({'error': '图片验证码错误'}, status=400)
        # 生成加密后的token数据
        tjs = TJS(settings.SECRET_KEY, 300)
        access_token = tjs.dumps({'mobile': mobile}).decode()


        return JsonResponse({
            'mobile': mobile,
            'access_token': access_token
        })


class SmsCode(APIView):
    def get(self, request):
        sms_code = request.query_params.get('sms_code')
        access_token = request.query_params.get('access_token')

        tjs = TJS(settings.SECRET_KEY, 300)
        mobile = tjs.loads(access_token)



        # # 判断access_token
        # conn = get_redis_connection('access_token')
        # real_token = conn.get('access_token_%s' % mobile)
        # if not real_token == access_token:
        #     return Response({'error': 'token值错误'})

        conn = get_redis_connection('access_token')
        flag = conn.get('sms_code_%s' % mobile)
        if flag:
            return Response({'error': '请求过于频繁'}, status=400)
        # 2、生成短信验证码
        sms_code = '%06d' % randint(0, 999999)
        print('图片验证码', sms_code)
        # 3、保存短信验证码到缓存中
        pl = conn.pipeline()  # 生成管道对象
        pl.setex('sms_code_%s' % mobile, 300, sms_code)
        pl.setex('sms_code_flag_%s' % mobile, 60, 1)
        pl.execute()  # 连接缓存，传入写入指令
        send_sms_code.delay(mobile, sms_code)
        # 5、结果返回
        return Response({'message': 'ok'})














